<template>
  <div class="container-box">
    <CommonCrud ref="crudRef" @search="handleSearch">
      <!-- 工具栏按钮 -->
      <template #table-header>
        <el-button v-permission="'system:role:add'" type="primary" @click="handleAdd">
          新增
        </el-button>
      </template>
      <el-table-column prop="name" label="角色标识" />
      <el-table-column prop="cnName" label="角色名称" />
      <el-table-column prop="role_desc" label="角色描述" />
      <template #operation="{ row }">
        <el-button v-permission="'system:role:edit'" link type="primary" @click="handleEdit(row)">
          编辑
        </el-button>
        <el-button v-permission="'system:role:del'" link type="danger" @click="handleDelete(row)">
          删除
        </el-button>
        <el-button v-permission="'system:role:per'" type="primary" link @click="handleAssignPermission(row)">
          分配权限
        </el-button>
      </template>
    </CommonCrud>
    <CommonDialog v-model="dialogVisible" :title="title" width="500px" @confirm="handleSubmit" @cancel="handleDialogClose"
      @close="handleDialogClose">
      <el-form ref="formRef" :model="formData" :rules="rules" label-width="100px">
        <el-form-item label="角色标识" prop="name">
          <el-input v-model="formData.name" placeholder="请输入角色标识" />
        </el-form-item>
        <el-form-item label="角色名称" prop="cnName">
          <el-input v-model="formData.cnName" placeholder="请输入角色名称" />
        </el-form-item>
        <el-form-item label="角色描述" prop="role_desc">
          <el-input v-model="formData.role_desc" placeholder="请输入角色描述" />
        </el-form-item>
      </el-form>
    </CommonDialog>
    <CommonDialog v-model="permissionDialogVisible" title="分配权限" width="500px" @confirm="handleSavePermission"
      @cancel="handleDialogPerClose" @close="handleDialogPerClose">
      <el-tree ref="menuTreeRef" :data="menuTreeData" :props="{ label: 'title' }" show-checkbox node-key="id"
        :default-checked-keys="checkedMenuIds" :check-strictly="true" />
    </CommonDialog>
  </div>
</template>

<script setup lang="ts">
import { ref, reactive, onMounted } from "vue"
import type { FormInstance } from "element-plus"
import type { TreeInstance } from "element-plus/es/components/tree/src/tree.type"
import CommonCrud from "@/components/CommonCrud/index.vue"
import {
  getRoleList,
  addRole,
  editRole,
  deleteRole,
  getRoleMenus,
  updateRoleMenus,
} from "@/api/role"
import { getMenuList } from "@/api/menu"
import { ElMessage, ElMessageBox } from "element-plus"

interface RoleData {
  id: number
  name: string
  cnName: string
  role_desc: string
  create_time?: string
  update_time?: string
}

interface RoleFormData {
  id?: number
  name: string
  cnName: string
  role_desc: string
}

interface MenuData {
  id: number
  title: string
  path: string
  icon?: string
  permission?: string
  parent_id: number
  sort: number
  level: number
  hidden: boolean
  children?: MenuData[]
}

const crudRef = ref()
const menuTreeRef = ref<TreeInstance>()
const permissionDialogVisible = ref(false)
const currentRole = ref<RoleData | null>(null)
const menuTreeData = ref<MenuData[]>([])
const checkedMenuIds = ref<number[]>([])
const dialogVisible = ref(false)
const title = ref("")
const formRef = ref()
const formData = ref<RoleFormData>({
  name: "",
  role_desc: "",
  cnName: ""
})
const handleDialogClose = () => {
  dialogVisible.value = false
  formRef.value.resetFields()
}
const handleDialogPerClose = () => {
  permissionDialogVisible.value = false
}
const handleAdd = () => {
  dialogVisible.value = true
  title.value = "新增"
}
// 表单校验规则
const rules = {
  name: [{ required: true, message: "请输入角色标识", trigger: "blur" }],
  cnName: [{ required: true, message: "请输入角色名称", trigger: "blur" }],
  role_desc: [{ required: true, message: "请输入角色描述", trigger: "blur" }],
}

// 获取角色列表
const handleSearch = async (params: any) => {
  try {
    crudRef.value.loading = true
    const res = (await getRoleList(params)) as ApiResponse<{
      list: RoleData[]
      total: number
    }>
    if (res.code === 200) {
      crudRef.value.tableData = res.data.data
      crudRef.value.total = res.data.total
    }
  } finally {
    crudRef.value.loading = false
  }
}

// 提交表单
const handleSubmit = async () => {
  if (title.value === "新增") {
    const res = await addRole(formData.value)
    if (res.code === 200) {
      ElMessage.success("添加成功")
      crudRef.value.handleSearch()
      handleDialogClose()
    }
  } else if (title.value === "编辑") {
    const res = await editRole(formData.value.id, formData.value)
    if (res.code === 200) {
      ElMessage.success("保存成功")
      crudRef.value.handleSearch()
      handleDialogClose()
    }
  }
}
const handleEdit = (row: RoleData) => {
  dialogVisible.value = true
  title.value = "编辑"
  formData.value = { ...row }
}
// 删除角色
const handleDelete = async (row: RoleData) => {
  ElMessageBox.confirm("确定要删除吗?", "警告", {
    confirmButtonText: "确定",
    cancelButtonText: "取消",
    type: "warning",
  })
    .then(async () => {
      const res = await deleteRole(row.id)
      if (res.code === 200) {
        ElMessage.success("删除成功")
        crudRef.value.handleSearch()
      }
    })
    .catch(() => {
      ElMessage({
        type: "info",
        message: "删除取消",
      })
    })
}
// 打开分配权限对话框
const handleAssignPermission = async (row: RoleData) => {
  currentRole.value = row
  // 先清空之前的选中状态
  checkedMenuIds.value = []
  // 先获取所有菜单树
  const menuRes = await getMenuList({})
  if (menuRes.code === 200) {
    menuTreeData.value = menuRes.data.tree
    // 再获取角色的权限
    const roleRes = await getRoleMenus(row.id)
    if (roleRes.code === 200) {
      checkedMenuIds.value = handleGetCheckedKeys(roleRes.data.menus)
      console.log(checkedMenuIds.value)

      permissionDialogVisible.value = true
    }
  }
}

const handleGetCheckedKeys = (menus: MenuData[]): number[] => {
  const checkedKeys: number[] = []
  const traverse = (items: MenuData[]) => {
    items.forEach((menu) => {
      checkedKeys.push(menu.id)
      if (menu.children && menu.children.length > 0) {
        traverse(menu.children)
      }
    })
  }
  traverse(menus)
  return checkedKeys
}

// 保存权限设置
const handleSavePermission = async () => {
  const checkedKeys = menuTreeRef.value.getCheckedKeys()
  const menuIds = checkedKeys

  const res = await updateRoleMenus(currentRole.value.id, menuIds)
  if (res.code === 200) {
    ElMessage.success("权限设置成功")
    permissionDialogVisible.value = false
  }
}

onMounted(() => {
  handleSearch({})
})
</script>

<style scoped lang="scss"></style>
